// TODO: CODE REVIEW & CLEANUP!
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using AxWMPLib;
using WMPLib;

namespace HomeUX.MusicServer
{

// represents a session with a single client
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class MusicWcfService : IMusicWcfService, IDisposable
{
    MusicServer _musicServer;
    IMusicWcfServiceCallback _callback;    

    // an instance of this class is created when each client connects
    public MusicWcfService()
    {
        _callback = OperationContext.Current.GetCallbackChannel<IMusicWcfServiceCallback>();
        _musicServer = MusicServer.OnClientConnected(this);
    }

    // called when the client disconnects
    public void Dispose()
    {
        if (_musicServer != null)
        {
            _musicServer.OnClientDisconnected(this);
            _musicServer = null;
        }
    }

    // report to client
    public void ReportStatusChange(MusicServiceStatus status)
    {
        try
        {
            if (_callback != null)
            {
                _callback.StatusChanged(status);
            }
        }
        catch (ObjectDisposedException)
        {
            // ignore -- it means client just disconnected
        }
    }

    public void ReportQueueChange(QueueDetails queueDetails)
    {
        try
        {
            if (_callback != null)
                _callback.QueueChanged(queueDetails);
        }
        catch (ObjectDisposedException)
        {
            // ignore -- it means client just disconnected
        }
    }

    public void ReportLibraryChange()
    {
        try
        {
            if (_callback != null)
                _callback.LibraryChanged();
        }
        catch (ObjectDisposedException)
        {
            // ignore -- it means client just disconnected
        }
    }

    public void ReportSettingsChange(MusicServiceSettings settings)
    {
        try
        {
            if (_callback != null)
                _callback.SettingsChanged(settings);
        }
        catch (ObjectDisposedException)
        {
            // ignore -- it means client just disconnected
        }
    }

    // IMusicWcfService implementation...

    void IMusicWcfService.Hello()
    {
    }

    void IMusicWcfService.Goodbye()
    {
        // Scenario: the client application exits, and in the process the client closes the
        // connection to the server -- but after that point (and before the connection is
        // fully shut down) a message is received from the server.  That causes a
        // ProtocolException on the client.  To reduce the odds of this, the client can call
        // Goodbye first, which will prevent further calls from server to client.
        _callback = null;
    }

    ArtistInfo[] IMusicWcfService.GetArtists()
    {
        return _musicServer.GetArtists();
    }

    AlbumInfo[] IMusicWcfService.GetAlbumsOfArtist(string artistName,
        GetAlbumsOfArtistOptions options)
    {
        return _musicServer.GetAlbumsOfArtist(artistName, options);
    }

    AlbumDetails IMusicWcfService.GetAlbumDetails(string albumId)
    {
        return _musicServer.GetAlbumDetails(albumId);
    }

    SearchResult IMusicWcfService.Search(SearchRequest searchRequest)
    {
        return _musicServer.Search(searchRequest);
    }

    QueueDetails IMusicWcfService.GetQueueDetails()
    {
        return _musicServer.GetQueueDetails();
    }

    void IMusicWcfService.PlayAlbum(string albumId, int startAtTrackNumber)
    {
        _musicServer.PlayAlbum(albumId, startAtTrackNumber);
    }

    void IMusicWcfService.AddToQueue(TrackId[] trackIds)
    {
        _musicServer.AddToQueue(trackIds);
    }

    void IMusicWcfService.RemoveFromQueue(TrackId[] trackIds)
    {
        _musicServer.RemoveFromQueue(trackIds);
    }

    void IMusicWcfService.ChangeQueue(TrackId[] trackIds)
    {
        _musicServer.ChangeQueue(trackIds);
    }

    void IMusicWcfService.ClearQueue()
    {
        _musicServer.ClearQueue();
    }
    PlaylistInfo[] IMusicWcfService.GetPlaylists()
    {
        return _musicServer.GetPlaylists();
    }

    void IMusicWcfService.LoadPlaylist(string playlistName)
    {
        _musicServer.LoadPlaylist(playlistName);
    }

    void IMusicWcfService.SaveQueue(string playlistName)
    {
        _musicServer.SaveQueue(playlistName);
    }

    void IMusicWcfService.DeletePlaylist(string playlistName)
    {
        _musicServer.DeletePlaylist(playlistName);
    }

    void IMusicWcfService.Play()
    {
        _musicServer.Play();
    }

    void IMusicWcfService.Pause()
    {
        _musicServer.Pause();
    }

    void IMusicWcfService.Stop()
    {
        _musicServer.Stop();
    }

    void IMusicWcfService.FastForward()
    {
        _musicServer.FastForward();
    }

    void IMusicWcfService.FastReverse()
    {
        _musicServer.FastReverse();
    }

    void IMusicWcfService.NextTrack()
    {
        _musicServer.NextTrack();
    }

    void IMusicWcfService.PreviousTrack()
    {
        _musicServer.PreviousTrack();
    }

    void IMusicWcfService.PlayQueueItem(TrackId trackId)
    {
        _musicServer.PlayQueueItem(trackId);
    }

    MusicServiceDetailedStatus IMusicWcfService.GetDetailedStatus()
    {
        return _musicServer.GetDetailedStatus();
    }

    MusicServiceSettings IMusicWcfService.GetSettings()
    {
        return _musicServer.GetSettings();
    }

    void IMusicWcfService.SetSettings(MusicServiceSettings settings)
    {
        _musicServer.SetSettings(settings);
    }
}

}
